﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;

namespace log4netudp {
    public partial class MainForm : Form {

        private Socket m_server_socket;
        private byte[] m_recive_data = new byte[65536];
        private delegate void AddTextDelegate(string logMsg);
        private Color m_time = Color.FromArgb(86, 199, 3);
        private Color m_debug = Color.FromArgb(240, 240, 240);
        private Color m_Info = Color.FromArgb(230, 230, 145);
        private Color m_Warn = Color.FromArgb(119, 238, 232);
        private Color m_Error = Color.FromArgb(249, 139, 134);
        private Color m_Fatal = Color.FromArgb(254, 22, 39);

        public MainForm() {
            InitializeComponent();
        }

        private void ReceiveData(IAsyncResult iar) {
            IPEndPoint client = new IPEndPoint(IPAddress.Any, 0);
            EndPoint epSender = (EndPoint)client;
            int recv_len = 0;
            try {
                recv_len = m_server_socket.EndReceiveFrom(iar, ref epSender);
            } catch (System.Exception) { }
            string recv_text = Encoding.UTF8.GetString(m_recive_data, 0, recv_len);
            OnAppendLog(recv_text);
            if(m_server_socket != null)
                m_server_socket.BeginReceiveFrom(m_recive_data, 0, m_recive_data.Length,
                    SocketFlags.None, ref epSender, new AsyncCallback(ReceiveData), epSender);
        }

        private void OnAppendLog(string logMsg) {
            if (tbLog.Disposing || tbLog.IsDisposed) return;
            if (tbLog.InvokeRequired && tbLog.IsHandleCreated)
                tbLog.Invoke(new AddTextDelegate(OnAppendLog), logMsg);
            else {
                if (logMsg.Length > 16) {
                    tbLog.SelectionStart = tbLog.TextLength;
                    tbLog.SelectionLength = 0;

                    tbLog.SelectionColor = m_time;
                    tbLog.AppendText(logMsg.Substring(0, 10));

                    string level = logMsg.Substring(12, 5);
                    if (level == "DEBUG")
                        tbLog.SelectionColor = m_debug;
                    else if (level == "INFO ")
                        tbLog.SelectionColor = m_Info;
                    else if (level == "WARN ")
                        tbLog.SelectionColor = m_Warn;
                    else if (level == "ERROR")
                        tbLog.SelectionColor = m_Error;
                    else if (level == "FATAL")
                        tbLog.SelectionColor = m_Fatal;

                    tbLog.AppendText(logMsg.Substring(10));
                }
                else tbLog.AppendText(logMsg);
            }
        }

        private void btnStart_Click(object sender, EventArgs e) {
            int port = 0;
            try {
                port = Int32.Parse(tbPort.Text);
            }
            catch (System.Exception ex) {
                MessageBox.Show("输入的端口号是无效数字", "错误");
                return;
            }
            if (port <= 0 || port >= 65535) {
                MessageBox.Show("端口号必须在1-65535之间", "错误");
                return;
            }

            try {
                m_server_socket = new Socket(AddressFamily.InterNetwork,
                    SocketType.Dgram, ProtocolType.Udp);
                IPEndPoint server = new IPEndPoint(IPAddress.Any, port);
                m_server_socket.Bind(server);
                IPEndPoint client = new IPEndPoint(IPAddress.Any, 0);
                EndPoint epSender = (EndPoint)client;
                m_server_socket.BeginReceiveFrom(m_recive_data, 0,
                    m_recive_data.Length, SocketFlags.None,
                        ref epSender, new AsyncCallback(ReceiveData), epSender);

                btnStart.Enabled = false;
                btnStop.Enabled = true;
            }
            catch (System.Exception ex) {
                MessageBox.Show(ex.Message, "错误");
                return;
            }
        }

        private void btnStop_Click(object sender, EventArgs e) {
            if (m_server_socket != null) {
                m_server_socket.Close();
                m_server_socket = null;
                btnStart.Enabled = true;
                btnStop.Enabled = false;
            }
        }

        private void btnClear_Click(object sender, EventArgs e) {
            tbLog.Clear();
        }

        private void btnCopy_Click(object sender, EventArgs e) {
            tbLog.SelectAll();
            tbLog.Copy();
            tbLog.DeselectAll();
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e) {
            if (m_server_socket != null)
                m_server_socket.Close();
        }

        private void btnHelp_Click(object sender, EventArgs e) {
            new AboutForm().ShowDialog();
        }
    }
}
